package com.blue.gateway.paycore.alipay.notify;

import com.blue.gateway.common.Request;
import com.blue.gateway.common.request.PayNotifyRequest;
import com.blue.gateway.common.response.PayNotifyResponse;
import com.blue.gateway.config.BaseChannelConfig;
import com.blue.gateway.dto.Result;
import com.blue.gateway.dto.ResultWrapper;
import com.blue.gateway.enums.PayChannelEnum;
import com.blue.gateway.annotation.Channel;
import com.blue.gateway.config.AliConfig;
import com.blue.gateway.paycore.AbstractBaseChannelService;
import com.blue.gateway.enums.ResultCodeEnum;
import com.blue.gateway.enums.ServiceChannelEnum;
import com.blue.gateway.utils.MapUtil;
import com.blue.gateway.utils.sign.AliPaySignature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.HashMap;

/**
 * @author xiaoyiming
 * @date 2020/5/3 22:53
 * @depiction 支付回调接口
 */
@Slf4j
@Channel(PayChannel = PayChannelEnum.ALIPAY, ServiceChannel = ServiceChannelEnum.PAY_NOTIFY)
public class AliPayNotifyService extends AbstractBaseChannelService {

    @Autowired
    private AliConfig aliConfig;


    @Override
    public Result validate(Request request) {
        PayNotifyRequest payNotifyRequest = (PayNotifyRequest) request;
        if (StringUtils.isBlank(payNotifyRequest.getNotifyData())) {
            return ResultWrapper.fail(ResultCodeEnum.PARAM_ILLEGAL);
        }
        return ResultWrapper.success();
    }

    @Override
    public BaseChannelConfig getConfig(Request request) {
        return aliConfig;
    }

    @Override
    public String generateParams(Request request, BaseChannelConfig channelConfig) {
        PayNotifyRequest payNotifyRequest = (PayNotifyRequest) request;
        return payNotifyRequest.getNotifyData();
    }

    @Override
    public String execute(String requestParams, BaseChannelConfig channelConfig) {
        AliConfig aliConfig = (AliConfig) channelConfig;
        String notifyData = null;
        try {
            notifyData = URLDecoder.decode(requestParams, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // do nothing
        }

        //签名校验
        if (!AliPaySignature.verify(MapUtil.form2Map(notifyData), aliConfig.getPublicKey(), aliConfig.getSignType())) {
            log.error("【支付宝支付异步通知】签名验证失败, response={}", notifyData);
            throw new RuntimeException("【支付宝支付异步通知】签名验证失败");
        }

        return notifyData;
    }
    //gmt_create=2020-05-04 22:13:53&charset=UTF-8&gmt_payment=2020-05-04 22:13:58&notify_time=2020-05-04 22:13:58&subject=测试一下&sign=eBX7X6fmqlJjTPtvVxE4VylUJs3HLJqdmvP8EIT3Bw/k4terCTTRZg9XaXj3DUmEh8WljN7zfQ61GlbL7a5MkmKyynwJ/LoTAnCUCMQ9WfJ3RhulKfDIkPgPDgBIDy2I2uYfueY+zwmRj6VCu6s6H84m90BsrvBw1OVrTqHUkBBD+tXIABWUP0Hy2DUoU9/wAjduk4pzf4lfMH5uG7n9Jqf7RNRBWQeg2Qaa3l28Bw1+hG/X3hwVv4BmGFpihidUjPd91cfTZLga6GshjPqp8r0PE0NF/eKoDsG/LA3mFTox2PsfQSu7ZfzQ1A2cv3oMPKfLuOmvdxlM3h1BEisC4g==&buyer_id=2088502959038209&invoice_amount=0.01&version=1.0&notify_id=2020050400222221358038201409719590&fund_bill_list=[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]&notify_type=trade_status_sync&out_trade_no=278987549888971&total_amount=0.01&trade_status=TRADE_SUCCESS&trade_no=2020050422001438201415871259&auth_app_id=2018062960540016&receipt_amount=0.01&point_amount=0.00&buyer_pay_amount=0.01&app_id=2018062960540016&sign_type=RSA2&seller_id=2088721207163940
    @Override
    public Result<PayNotifyResponse> analysisResult(String executeResult) {
        PayNotifyResponse payNotifyResponse = new PayNotifyResponse();
        try {
            HashMap<String, String> resultParams = MapUtil.form2MapWithCamelCase(executeResult);
            payNotifyResponse.setTradeNo(resultParams.get("tradeNo"));
            payNotifyResponse.setOrderId(resultParams.get("outTradeNo"));
            payNotifyResponse.setTotalAmount(new BigDecimal(resultParams.get("totalAmount")));
            payNotifyResponse.setInvoiceAmount(new BigDecimal(resultParams.get("invoiceAmount")));
            payNotifyResponse.setTradeStatus(resultParams.get("tradeStatus"));
            payNotifyResponse.setNotifyTime(resultParams.get("notifyTime"));
        } catch (Exception e) {
            //
        }
        return ResultWrapper.success(payNotifyResponse);
    }
    /**
     * resultParams:
     * * {
     * "charset":"UTF-8",
     * "pointAmount":"0.00",
     * "tradeNo":"2020050422001438201415871259",
     * "notifyTime":"2020-05-04 22:13:58",
     * "subject":"测试一下",
     * "sign":"eBX7X6fmqlJjTPtvVxE4VylUJs3HLJqdmvP8EIT3Bw/k4terCTTRZg9XaXj3DUmEh8WljN7zfQ61GlbL7a5MkmKyynwJ/LoTAnCUCMQ9WfJ3RhulKfDIkPgPDgBIDy2I2uYfueY+zwmRj6VCu6s6H84m90BsrvBw1OVrTqHUkBBD+tXIABWUP0Hy2DUoU9/wAjduk4pzf4lfMH5uG7n9Jqf7RNRBWQeg2Qaa3l28Bw1+hG/X3hwVv4BmGFpihidUjPd91cfTZLga6GshjPqp8r0PE0NF/eKoDsG/LA3mFTox2PsfQSu7ZfzQ1A2cv3oMPKfLuOmvdxlM3h1BEisC4g",
     * "invoiceAmount":"0.01",
     * "gmtCreate":"2020-05-04 22:13:53",
     * "buyerId":"2088502959038209",
     * "version":"1.0",
     * "totalAmount":"0.01",
     * "receiptAmount":"0.01",
     * "notifyType":"trade_status_sync",
     * "sellerId":"2088721207163940",
     * "gmtPayment":"2020-05-04 22:13:58",
     * "outTradeNo":"278987549888971",
     * "tradeStatus":"TRADE_SUCCESS",
     * "appId":"2018062960540016",
     * "buyerPayAmount":"0.01",
     * "signType":"RSA2",
     * "notifyId":"2020050400222221358038201409719590",
     * "fundBillList":"[{"amount":"0.01","fundChannel":"PCREDIT"}]",
     * "authAppId":"2018062960540016"
     * }
     *
     */
}
